from flask import Blueprint, flash, g, redirect, render_template, request, url_for
from werkzeug.exceptions import abort
from flask_paginate import Pagination, get_page_parameter

from flaskr.auth import login_required
from flaskr.database import db_session
from flaskr.models import Post

bp = Blueprint("blog", __name__)


@bp.route("/")
def index():
    page = request.args.get(get_page_parameter(), type=int, default=1)
    posts = Post.query.order_by(Post.created.desc()).offset((page-1)*10).limit(10)
    total = Post.query.count()
    pagination = Pagination(page=page, total=total, alignment="center")
    return render_template("blog/index.html", posts=posts, pagination=pagination)


@bp.route("/create", methods=("GET", "POST"))
@login_required
def create():
    if request.method == "POST":
        title = request.form["title"]
        body = request.form["body"]
        error = None

        if not title:
            error = "Title is required."

        if error is not None:
            flash(error)
        else:
            post = Post(title=title, body=body, author_id=g.user.id)
            db_session.add(post)
            db_session.commit()
            return redirect(url_for("blog.index"))

    return render_template("blog/create.html")


def get_post(pk, check_author=True):
    post = Post.query.filter(Post.id == pk).first()

    if post is None:
        abort(404, f"Post id {pk} doesn't exist.")

    if check_author and post.author_id != g.user.id:
        abort(403)

    return post


@bp.route("/<int:pk>/update", methods=("GET", "POST"))
@login_required
def update(pk):
    post = get_post(pk)

    if request.method == "POST":
        title = request.form["title"]
        body = request.form["body"]
        error = None

        if not title:
            error = "Title is required."

        if error is not None:
            flash(error)
        else:
            Post.query.filter(Post.id == pk).update(
                {"title": title, "body": body}
            )
            db_session.commit()
            return redirect(url_for("blog.index"))

    return render_template("blog/update.html", post=post)


@bp.route("/<int:pk>/delete", methods=("POST",))
@login_required
def delete(pk):
    get_post(pk)
    Post.query.filter(Post.id == pk).delete()
    db_session.commit()
    return redirect(url_for("blog.index"))
